package com.karolak.stock.strategy;

import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;

import org.jfree.ui.RefineryUtilities;

import com.karolak.math.view.ChartInd;
import com.karolak.stock.indicator.EmaInd;
import com.karolak.stock.indicator.FftInd;
import com.karolak.stock.indicator.HighInd;
import com.karolak.stock.indicator.HighTrInd;
import com.karolak.stock.indicator.HorizontalInd;
import com.karolak.stock.indicator.Indicator;
import com.karolak.stock.indicator.LowInd;
import com.karolak.stock.indicator.LowTrInd;
import com.karolak.stock.indicator.PropertyInd;
import com.karolak.stock.indicator.SumInd;
import com.karolak.stock.oscilator.BandOsc;
import com.karolak.stock.oscilator.BandSwOsc;
import com.karolak.stock.oscilator.BandTrOsc;
import com.karolak.stock.oscilator.CrossCounterOsc;
import com.karolak.stock.oscilator.CrossFreeOsc;
import com.karolak.stock.oscilator.CrossOsc;
import com.karolak.stock.oscilator.DeltaOsc;
import com.karolak.stock.oscilator.DiffOsc;
import com.karolak.stock.oscilator.SwitchOsc;

public class SwStrategy extends Strategy {

	@Override
	protected String defineConfig() {

		//return "{signalThreshold:0.0001,chartSize:12000,votingThreshold:0.75,period:15,periodMultipliers:[20],fftPeriod:512}";
		return "{signalThreshold:0.0001,chartSize:11024,votingThreshold:0.6,period:15,periodMultipliers:[20],fftPeriod:512}";
		// return "{signalThreshold:0.0001,votingThreshold:0.75,period:15,periodMultipliers:[20],chartSize:10240,fftPeriod:512}";
		// return "{signalThreshold:0.0001,votingThreshold:0.75,period:15,periodMultipliers:[20],chartSize:30240,fftPeriod:512}";
	}

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				ChartInd frame = new ChartInd("hw");
				frame.pack();
				RefineryUtilities.centerFrameOnScreen(frame);
				frame.setVisible(true);
				// demo.start();
			}
		});
	}

	@Override
	protected List<Indicator> defineVoters() {

		String chBase = "base";
		String chDelta = false ? "delta" : null;
		String chDiff = false ? "diff" : null;
		String chFftHr = false ? "fft.hr" : null;
		String chFftAmp = false ? "fft.amp" : null;
		String chFftPr = false ? "fft.pr" : null;
		String chOne = false ? "one" : null;
		String chSwitch = false ? "switch" : null;
		
		String chFftSignAmp = false ? "fft.singAmp" : null;
		
		List<Indicator> voters = new ArrayList<Indicator>();

		Indicator price = getDataManager().addSeries(new Indicator("Price", getDataManager()), chBase);
		Indicator emaf = null;
		for (int p : getConfig().getPeriods()) {

			// chbase null
			Indicator ema = getDataManager().addSeries(new EmaInd(getDataManager(), p, price), null);
			if (emaf == null) {
				emaf = price;
			}

			DiffOsc diffEma = getDataManager().addSeries(new DiffOsc(getDataManager(), p, emaf, ema), null);
			emaf = ema;

			DeltaOsc emaDelta = getDataManager().addSeries(new DeltaOsc(getDataManager(), ema, p, 0.0001), null);
			
			Indicator low = getDataManager().addSeries(new LowInd(getDataManager(), p, price), null);
			Indicator high = getDataManager().addSeries(new HighInd(getDataManager(), p, price), null);
			DiffOsc downForce = getDataManager().addSeries(new DiffOsc("DownForce." + p, getDataManager(), p, price, high), null);
			DiffOsc upForce = getDataManager().addSeries(new DiffOsc("UpForce." + p, getDataManager(), p, price, low), null);
			SumInd force = getDataManager().addSeries(new SumInd("Force." + p, getDataManager(), downForce, upForce), null);
			// EmaInd emavf = getDataManager().addSeries(new
			// EmaInd(getDataManager(), getConfig().getFftPeriod(), price),
			// chBase);

			
			HighTrInd highTr = getDataManager().addSeries(new HighTrInd(getDataManager(), p, price), null);
			LowTrInd lowTr = getDataManager().addSeries(new LowTrInd(getDataManager(), p, price), null);
			DiffOsc shortForce = getDataManager().addSeries(new DiffOsc("ShortForce." + p, getDataManager(), p, price, highTr), null);
			DiffOsc longForce = getDataManager().addSeries(new DiffOsc("LongForce." + p, getDataManager(), p, price, lowTr), null);
			SumInd trForce = getDataManager().addSeries(new SumInd("TrForce." + p, getDataManager(), shortForce, longForce), null);
			
			
			
			int fftHarmonicCount = 3;
			FftInd fft = getDataManager().addSeries(new FftInd(getDataManager(), getConfig().getFftPeriod(), price, fftHarmonicCount), null);
			Indicator[] hrs = new Indicator[fftHarmonicCount]; 
			hrs[0] = getDataManager().addSeries(new PropertyInd("hr.0", getDataManager(),  fft, "fft.hrLast", 0), chBase);
			for (int i = 1; i < fftHarmonicCount; i++) {
				hrs[i] = getDataManager().addSeries(new PropertyInd("hr." + i, getDataManager(),  fft, "fft.hrLast", i), chFftHr);
			}
			
			DeltaOsc hr0Delta = getDataManager().addSeries(new DeltaOsc(getDataManager(), hrs[0], getConfig().getFftPeriod(), 0.0001), null);
			
			Indicator hr0High = getDataManager().addSeries(new HighInd(getDataManager(), getConfig().getFftPeriod(),  hrs[0]), null);
			Indicator hr0Low = getDataManager().addSeries(new LowInd(getDataManager(), getConfig().getFftPeriod(),  hrs[0]), null);
			
			DiffOsc hr0HighLowDiff = getDataManager().addSeries(new DiffOsc("Hr0HlDiff", getDataManager(), hr0High, hr0Low), chFftAmp);

			

			for (int i = 0; i < fftHarmonicCount; i++) {
//				getDataManager().addSeries(new PropertyInd("fr." + i, getDataManager(),  fft, "fft.frequency", i), "fft.fr");
			}

			for (int i = 1; i < fftHarmonicCount; i++) {
				getDataManager().addSeries(new PropertyInd("pr." + i, getDataManager(),  fft, "fft.period", i), chFftPr);
			}

			Indicator[] amps = new Indicator[fftHarmonicCount]; 
			for (int i = 1; i < fftHarmonicCount; i++) {
				amps[i] = getDataManager().addSeries(new PropertyInd("amp." + i, getDataManager(),  fft, "fft.amplitude", i), chFftAmp);
			}


			
			DiffOsc diffFft = getDataManager().addSeries(new DiffOsc(getDataManager(), p, price, fft), null);
			DiffOsc diffHr0 = getDataManager().addSeries(new DiffOsc(getDataManager(), p, price, hrs[0]), chDiff);
			
//			IntegralInd intDiffHr0 = getDataManager().addSeries(new IntegralInd(getDataManager(),  getConfig().getFftPeriod()  , diffHr0), chDiff);
		//	EmaInd emaDiffHr0 = getDataManager().addSeries(new EmaInd(getDataManager(),  getConfig().getFftPeriod() , diffHr0), chDiff);
			

//			Indicator signAmp = getDataManager().addSeries(new SignAmplitudeInd("singAmp.1", getDataManager(),  amps[1], trForce), chFftSignAmp);

			SumInd highBand1 = getDataManager().addSeries(new SumInd("hB1." + p, getDataManager(), hrs[0], amps[1]), chBase);
			DiffOsc lowBand1 = getDataManager().addSeries(new DiffOsc("lB1." + p, getDataManager(), hrs[0], amps[1]), chBase);

			DiffOsc highOsc = getDataManager().addSeries(new DiffOsc("highOsc", getDataManager(), price, highBand1), chDiff);
			DiffOsc lowOsc = getDataManager().addSeries(new DiffOsc("lowOsc", getDataManager(), price, lowBand1), chDiff);
			SumInd highLowOsc = getDataManager().addSeries(new SumInd("highLowOsc", getDataManager(), highOsc, lowOsc), chDiff);
			
			HighInd lastHigh = getDataManager().addSeries(new HighInd(getDataManager(), getConfig().getFftPeriod(), highOsc), chDiff);
			LowInd lastLow = getDataManager().addSeries(new LowInd(getDataManager(), getConfig().getFftPeriod(), lowOsc), chDiff);
			
			//SwitchOsc switcher = getDataManager().addSeries(new SwitchOsc("switchHighLowOsc", getDataManager(), highLowOsc, highOsc, lowOsc,lastHigh, lastLow), null/*"swith"*/);			
//			SwitchOsc switcher = getDataManager().addSeries(new SwitchOsc("switchHighLowOsc", getDataManager(), highLowOsc, highOsc, lowOsc,lastHigh, lastLow), null/*"swith"*/);
			//SwitchOsc switcher = getDataManager().addSeries(new SwitchOsc("switchHighLowOsc", getDataManager(), highOsc, highOsc, lowOsc,lastHigh, lastLow), null/*"swith"*/);
			
			
			SumInd highBand2 = getDataManager().addSeries(new SumInd("hB2." + p, getDataManager(), hrs[0], amps[2]), chBase);
			DiffOsc lowBand2 = getDataManager().addSeries(new DiffOsc("lB2." + p, getDataManager(), hrs[0], amps[2] ), chBase);


			BandTrOsc bandTrOsc = getDataManager().addSeries(new BandTrOsc("bandTrOsc." + p, getDataManager(), price, lowBand1, highBand1), null);
			BandSwOsc bandSwOsc = getDataManager().addSeries(new BandSwOsc("bandSwOsc." + p, getDataManager(), price, lowBand1, highBand1, lowBand2, highBand2), null);

			DiffOsc diffOsc = getDataManager().addSeries(new DiffOsc("diffAmpOsc." + p, getDataManager(), amps[1], amps[2]) , chSwitch);
			HorizontalInd switchLevel =  getDataManager().addSeries(new HorizontalInd(0.0001), chSwitch); 

			CrossOsc crosser = getDataManager().addSeries(new CrossOsc(getDataManager(), getConfig().getFftPeriod(), hrs[0], price), "cross");
			CrossCounterOsc crossCtr = getDataManager().addSeries(new CrossCounterOsc(getDataManager(), getConfig().getFftPeriod(), crosser), "cross");
			CrossFreeOsc crossFree = getDataManager().addSeries(new CrossFreeOsc(getDataManager(), getConfig().getFftPeriod(), crosser), null);

			SwitchOsc switcher = getDataManager().addSeries(new SwitchOsc("switchHighLowOsc", getDataManager(), highLowOsc, highOsc, lowOsc, crossCtr, crossFree), "switch");
			
			
//			SwitchOsc(String name, DataManager dataManager, Indicator input0, Indicator high, Indicator low)
//			SwitchOsc switcher = getDataManager().addSeries(new SwitchOsc("switcher", getDataManager(), hr0HighLowDiff, amps[1], amps[2]), null);
			//DiffOsc switcher = getDataManager().addSeries(new DiffOsc("switcher", getDataManager(), hr0HighLowDiff, amps[1]), "switch");
			
			BandOsc bandOsc = getDataManager().addSeries(new BandOsc("bandOsc." + p, getDataManager(), switcher, bandTrOsc, bandSwOsc), chDelta);
			
			//BandOsc bandOsc = getDataManager().addSeries(new BandOsc("bandOsc." + p, getDataManager(), diffOsc, bandTrOsc, bandSwOsc), chDelta);
			

//			DivOsc divOsc = getDataManager().addSeries(new DivOsc("divOsc." + p, getDataManager(), amps[2], amps[1]), "div");	
			
			// chDiff
//			DiffOsc ampl = getDataManager().addSeries(new DiffOsc("Amp", getDataManager(), p, low, high), null);

//			LossOsc trOsc = getDataManager().addSeries(new LossOsc(getDataManager(), p, lowTr, highTr), null);

//			Indicator band = getDataManager().addSeries(new DiffOsc(getDataManager(), p, low, high), null);
//			DiffOsc diffDown = getDataManager().addSeries(new DiffOsc(getDataManager(), p, high, price), null);
//			DiffOsc diffUp = getDataManager().addSeries(new DiffOsc(getDataManager(), p, low, price), null);
//			SumInd trend = getDataManager().addSeries(new SumInd(getDataManager(), p, diffDown, diffUp), null);

			// DiffOsc fftPriceDiffOsc = getDataManager().addSeries(new	 DiffOsc(getDataManager(), p, fft, price), chDiff);

//			Indicator emaTrend = getDataManager().addSeries(new EmaInd(getDataManager(), p, trend), null);
//			voters.add(diffEma);
//			voters.add(force);
//			voters.add(trForce);
//			
//			 voters.add(diffFft);
//			 voters.add(diffHr0);
//			 
//			 voters.add(emaDelta);
//			 voters.add(hr0Delta);
//			 voters.add(signAmp);
			
//			 voters.add(switcher);
			
			 
			
//			 voters.add(highLowOsc);
//			 voters.add(bandTrOsc);
//			 voters.add(bandSwOsc);
			 voters.add(bandOsc);
			 
			 
			 
//			 voters.add(signAmp);
//			 voters.add(getDataManager().getIndicators().get("ampl.1"));
			// voters.add(trend);
			// voters.add(emaTrend);
			// voters.add(trOsc);
			// voters.add(fftPriceDiffOsc);
		}
		return voters;
	}
}
